package com.atguigu.srb.core.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.atguigu.srb.core.mapper.DictMapper;
import com.atguigu.srb.core.pojo.dto.ExcelDictDTO;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

/**
 * Alibaba EasyExcel - 监听器
 * @author bing  @create 2021/4/8-下午3:35
 */
@NoArgsConstructor // 通过无参 有参 构造函数把 mapper 注入进来
@Slf4j
public class ExcelDictDTOListener extends AnalysisEventListener<ExcelDictDTO> {

    private DictMapper dictMapper; // 通过无参 有参 构造函数把 mapper 注入进来

    // 准备数据列表容器（把读取的数据先放到列表，达到一定量再上传）
    private List<ExcelDictDTO> list = new ArrayList<>();
    // 每隔 5（3000） 条记录批量存储一次数据
    // 生产环境 3000 条记录批量存储一次, 开发环境 5条 批量存储一次
    // static final int BATCH_COUNT = 3000;
    private static final int BATCH_COUNT = 5;

    // 通过无参 有参 构造函数把 mapper 注入进来
    public ExcelDictDTOListener(DictMapper dictMapper) {
        this.dictMapper = dictMapper;
    }

    @Override
    public void invoke(ExcelDictDTO data, AnalysisContext analysisContext) {
        // 监听器负责把底层封装好的数据拿出来，调用 mapper 方法保存数据
        log.info("解析到一条记录:{}", data);
        // 将数据存入数据列表
        list.add(data);
        if (list.size() >= BATCH_COUNT) {
            saveData();
            list.clear(); // 清空列表
        }

    }

    // 保存数据方法
    private void saveData() {
        log.info("{} 条数据被存储到数据库....",list.size());
        // 调用 mapper 层的批量 save 方法：save list对象
        dictMapper.insertBatch(list); // 要自己写此方法
        log.info("{} 条数据存储到数据库成功！",list.size());
    }


    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 当最后剩余的数据记录数不足 BATCH_COUNT 时，最终一次性存储剩余数据
        saveData();
        log.info("所有数据解析完成！");

    }
}
